package rpcx

import (
	handler_common "clean/adapter/io/common"
	"clean/infra/config"
	"clean/infra/io"
	"clean/infra/io/driver"
	"clean/usecase"
	"clean/usecase/io/pb"
	"context"
	"github.com/smallnest/rpcx/server"
)

type ioDriver struct {
}

func init() {
	io.Register("rpc_rpcx", &ioDriver{})
}

func (ioDriver) Create(cfg config.Config, app usecase.Input) (io_driver.Io, error) {
	return NewServerRpcx(cfg, app)
}

// https://rpcx.io/
type ServerRpcx struct {
	rpcx   *server.Server
	router *io_driver.CommonRouter
}

func NewServerRpcx(cfg config.Config, app usecase.Input) (*ServerRpcx, error) {
	s := &ServerRpcx{
		router: &io_driver.CommonRouter{},
		rpcx:   server.NewServer(),
	}
	err := s.rpcx.RegisterFunctionName("Serve", "Serve", s.Serve, "")
	if err != nil {
		panic(err)
	}
	h := handler_common.NewHandler(app)
	h.Init(s.router)
	return s, nil
}

func (s *ServerRpcx) Serve(ctx context.Context, in *pb.Input, out *pb.Output) error {
	ir := in.ProtoReflect()
	wd := ir.WhichOneof(ir.Descriptor().Oneofs().Get(0))
	if wd == nil {
		out.Error = &pb.Error{
			Err: 1,
			Msg: "不认识的wd",
		}
		return nil
	}
	handler := s.router.Get(string(wd.Name()))
	if handler == nil {
		out.Error = &pb.Error{
			Err: 1,
			Msg: "不认识的wd",
		}
		return nil
	}
	handler(*in, out)
	return nil
}

func (s *ServerRpcx) Start() error {
	return s.rpcx.Serve("tcp", ":8081")
}
